#include "StdAfx.h"

#include "Registry.h"

LONG CKey::Create(HKEY parentKey, LPCTSTR keyName,
				  LPTSTR keyClass, DWORD options, REGSAM accessMask,
				  LPSECURITY_ATTRIBUTES securityAttributes, LPDWORD disposition)
{
	DWORD dispositionReal;
	HKEY key = NULL;
	LONG res = RegCreateKeyEx(parentKey, keyName, 0, keyClass,
		options, accessMask, securityAttributes, &key, &dispositionReal);
	if (disposition != NULL)
		*disposition = dispositionReal;
	if (res == ERROR_SUCCESS)
	{
		res = Close();
		_object = key;
	}
	return res;
}
LONG CKey::Open(HKEY parentKey, LPCTSTR keyName, REGSAM accessMask)
{
	HKEY key = NULL;
	LONG res = RegOpenKeyEx(parentKey, keyName, 0, accessMask, &key);
	if (res == ERROR_SUCCESS)
	{
		res = Close();
		_object = key;
	}
	return res;
}

LONG CKey::Close()
{
	LONG res = ERROR_SUCCESS;
	if (_object != NULL)
	{
		res = RegCloseKey(_object);
		_object = NULL;
	}
	return res;
}

LONG CKey::DeleteSubKey(LPCTSTR subKeyName)//
{
	return RegDeleteKey(_object, subKeyName);
}

LONG CKey::RecurseDeleteKey(LPCTSTR subKeyName)///////
{
	CKey key;
	LONG res = key.Open(_object, subKeyName, KEY_READ | KEY_WRITE);
	if (res != ERROR_SUCCESS)
		return res;
	FILETIME fileTime;
	const unsigned int kBufferSize = MAX_PATH + 1; // 256 in ATL
	DWORD size = kBufferSize;
	TCHAR buffer[kBufferSize];
	while (RegEnumKeyEx(key._object, 0, buffer, &size, NULL, NULL, NULL, &fileTime) == ERROR_SUCCESS)
	{
		res = key.RecurseDeleteKey(buffer);
		if (res != ERROR_SUCCESS)
			return res;
		size = kBufferSize;
	}
	key.Close();
	return DeleteSubKey(subKeyName);
}

LONG CKey::SetValue(LPCTSTR name, LPCTSTR value)///
{
	return RegSetValueEx(_object, name, NULL, REG_SZ,
		(const BYTE * )value, (lstrlen(value) + 1) * sizeof(TCHAR));
}

LONG CKey::SetValue(LPCTSTR name, DWORD &value)///
{
	return RegSetValueEx(_object, name, NULL, REG_DWORD,
		(const BYTE * )&value, sizeof(DWORD));
}

LONG CKey::QueryValue(LPCTSTR name, LPTSTR value, unsigned int &count)
{
	
	DWORD type = NULL;
	LONG res = RegQueryValueEx(_object, (LPTSTR)name, NULL, &type, (LPBYTE)value, (DWORD *)&count);
	return res;
}

LONG CKey::QueryValue(LPCTSTR name, TString &value)
{
	value.Empty();
	DWORD type = NULL;
	unsigned int currentSize = 0;
	LONG res = RegQueryValueEx(_object, (LPTSTR)name, NULL, &type, NULL, (DWORD *)&currentSize);
	if (res != ERROR_SUCCESS && res != ERROR_MORE_DATA)
		return res;
	TCHAR* pValue = new TCHAR[currentSize];
	res = QueryValue(name, pValue, currentSize);
	value = pValue;
	delete [] pValue;

	return res;
}

BOOL CKey::GetUnInstallName( std::wstring &vecInstallName )
{
	std::wstring wsKeyName = L"SoftWare\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\";
	wsKeyName += vecInstallName;
	LONG res = Open(HKEY_LOCAL_MACHINE, wsKeyName.c_str(), KEY_READ );
	if (res != ERROR_SUCCESS)
		return FALSE;
	Close();
	
	return TRUE;
}


